<template>
  <div class="chat-container">
    <!-- 文件预览对话框 -->
    <el-dialog v-model="previewVisible" title="文件预览" width="80%" :destroy-on-close="true">
      <div class="preview-container">
        <img v-if="previewUrl && previewUrl.match(/\.(jpeg|jpg|gif|png)$/i)" :src="previewUrl" class="preview-content" />
        <video v-else-if="previewUrl && previewUrl.match(/\.(mp4|webm|ogg)$/i)" :src="previewUrl" controls class="preview-content"></video>
        <audio v-else-if="previewUrl && previewUrl.match(/\.(mp3|wav|ogg)$/i)" :src="previewUrl" controls class="preview-content"></audio>
        <iframe v-else-if="previewUrl && previewUrl.match(/\.(pdf)$/i)" :src="previewUrl" class="preview-content pdf-preview"></iframe>
        <div v-else class="preview-error">无法预览此类型文件</div>
      </div>
    </el-dialog>
    
    <!-- 左侧会话列表 -->
    <div class="chat-sidebar">
      <div class="sidebar-header">
        <el-button type="primary" @click="createNewChat" class="new-chat-btn">新建会话</el-button>
      </div>
      <div class="chat-list">
        <el-empty v-if="chatIds.length === 0" description="暂无会话记录" />
        <div 
          v-else
          v-for="id in chatIds" 
          :key="id" 
          @click="selectChat(id)"
          :class="{'active': currentChatId === id}"
          class="chat-item">
          <span class="chat-title">{{ getChatTitle(id) }}</span>
          <el-button @click.stop="deleteChat(id)" type="danger" size="small" circle class="delete-btn">
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
      </div>
    </div>
    
    <!-- 右侧聊天区域 -->
    <div class="chat-main">
      <!-- 消息列表 -->
      <div class="message-list" ref="messageList">
        <el-empty v-if="messages.length === 0" description="暂无消息，开始聊天吧" />
        <div v-else v-for="(msg, index) in messages" :key="index" :class="['message', `message-${msg.role}`]">
          <template v-if="msg.role === 'user'">
            <div class="message-content user-message" v-html="msg.content"></div>
            <div class="message-avatar">
              <el-avatar 
                :size="40" 
                :src="userAvatar" 
                type="primary"
              ></el-avatar>
            </div>
          </template>
          <template v-else>
            <div class="message-avatar">
              <el-avatar 
                :size="40" 
                :src="aiAvatar" 
                type="success"
              ></el-avatar>
            </div>
            <div class="message-content ai-message" v-html="formatMessageContent(msg.content)"></div>
          </template>
        </div>
        <div v-if="isLoading" class="message message-assistant">
          <div class="message-avatar">
            <el-avatar :size="40" :src="aiAvatar" type="success"></el-avatar>
          </div>
          <div class="message-content ai-message loading">
            <span class="dot"></span>
            <span class="dot"></span>
            <span class="dot"></span>
          </div>
        </div>
      </div>
      
      <!-- 输入区域 -->
      <div class="input-area">
        <div class="file-upload">
          <el-upload
            action="#"
            :auto-upload="false"
            :on-change="handleFileChange"
            :on-remove="handleFileRemove"
            :limit="5"
            multiple
            :file-list="fileList"
            accept="image/*,audio/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt"
            class="upload-demo">
            <template #trigger>
              <el-button type="primary" :icon="Plus">选择文件</el-button>
            </template>
            <template #tip>
              <div class="el-upload__tip" v-if="fileList.length > 0">
                已选择 {{ fileList.length }} 个文件
              </div>
            </template>
          </el-upload>
        </div>
        <div class="input-wrapper">
          <el-input
            v-model="userInput"
            type="textarea"
            :rows="3"
            placeholder="输入消息，Ctrl+Enter或回车发送"
            resize="none"
            @keydown.ctrl.enter="handleSendMessage"
            @keydown.enter.exact.prevent="handleSendMessage"
          />
          <el-button 
            type="primary" 
            @click="handleSendMessage" 
            :disabled="!userInput.trim() && fileList.length === 0"
            :loading="isLoading"
            class="send-btn">
            发送
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { Delete } from '@element-plus/icons-vue';
import { ref, onMounted, nextTick, watch } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getChatHistoryIds, getChatMessages, sendChatMessage, deleteChatHistory, saveChatIds } from '../api/chat';

// 状态变量
const chatIds = ref([]); // 会话ID列表
const currentChatId = ref(''); // 当前选中的会话ID
const messages = ref([]); // 当前会话的消息列表
const userInput = ref(''); // 用户输入
const fileList = ref([]); // 上传的文件列表
const isLoading = ref(false); // 是否正在加载AI回复
const messageList = ref(null); // 消息列表DOM引用
const chatTitles = ref({}); // 会话标题映射

// 头像设置
const userAvatar = ref('https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png');
const aiAvatar = ref('https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png');

// 文件预览相关
const previewVisible = ref(false);
const previewFile = ref(null);
const previewUrl = ref('');

// 格式化消息内容，处理图片和表格等
const formatMessageContent = (content) => {
  if (!content) return '';
  
  // 处理HTML表格
  if (content.includes('<table>')) {
    return content;
  }
  
  // 处理图片标签，添加点击预览功能
  if (content.includes('<img')) {
    // 将原生<img>标签替换为可点击预览的图片
    return content.replace(/<img\s+src="([^"]+)"[^>]*>/g, (match, src) => {
      return `<div class="image-preview-wrapper" @click="showImagePreview('${src}')"><img src="${src}" class="preview-image" /></div>`;
    });
  }
  
  // 处理音频标签，添加播放控件
  if (content.includes('<audio')) {
    return content.replace(/<audio\s+src="([^"]+)"[^>]*>/g, (match, src) => {
      return `<audio src="${src}" controls class="media-player"></audio>`;
    });
  }
  
  // 处理视频标签，添加播放控件
  if (content.includes('<video')) {
    return content.replace(/<video\s+src="([^"]+)"[^>]*>/g, (match, src) => {
      return `<video src="${src}" controls class="media-player"></video>`;
    });
  }
  
  // 处理普通文本，保留换行
  return content.replace(/\n/g, '<br>');
};

// 显示图片预览
 const showImagePreview = (url) => {
   previewUrl.value = url;
   previewVisible.value = true;
 };

// 生成唯一会话ID
const generateChatId = () => {
  return String(Date.now()); // 确保返回字符串类型
};

// 获取会话标题
const getChatTitle = (id) => {
  // 确保id是字符串
  const chatId = String(id);
  
  // 如果有自定义标题，优先使用自定义标题
  if (chatTitles.value && chatTitles.value[chatId]) {
    return chatTitles.value[chatId];
  }
  
  // 如果没有自定义标题，则使用ID的前15个字符
  return chatId.substring(0, 15) + '...';
};

// 创建新会话
const createNewChat = () => {
  const newChatId = generateChatId();
  currentChatId.value = newChatId;
  
  // 确保chatIds.value是数组
  if (!Array.isArray(chatIds.value)) {
    chatIds.value = [];
  }
  
  chatIds.value = [newChatId, ...chatIds.value];
  messages.value = [];
  userInput.value = '';
  fileList.value = [];
  
  // 确保chatTitles.value是对象
  if (!chatTitles.value) {
    chatTitles.value = {};
  }
  
  // 设置默认标题
  chatTitles.value[newChatId] = '新对话 ' + new Date().toLocaleTimeString();
  
  // 将标题保存到本地存储
  saveChatTitles();
  
  // 将聊天ID列表保存到本地存储
  saveChatIds(chatIds.value);
};

// 保存会话标题到本地存储
const saveChatTitles = () => {
  try {
    localStorage.setItem('chatTitles', JSON.stringify(chatTitles.value));
  } catch (error) {
    console.error('保存会话标题失败:', error);
  }
};

// 从本地存储加载会话标题
const loadChatTitles = () => {
  try {
    const savedTitles = localStorage.getItem('chatTitles');
    if (savedTitles) {
      chatTitles.value = JSON.parse(savedTitles);
    }
  } catch (error) {
    console.error('加载会话标题失败:', error);
  }
};

// 加载会话历史列表
const loadChatHistory = async () => {
  try {
    // 先加载本地存储的标题
    loadChatTitles();
    
    // 确保chatIds.value初始化为空数组
    chatIds.value = [];
    
    try {
      const result = await getChatHistoryIds();
      console.log('获取到的历史会话数据:', result);
      
      // 检查返回的数据
      if (result && result.data && Array.isArray(result.data)) {
        // 后端API返回了标准格式的响应
        chatIds.value = result.data.map(id => String(id));
      } else if (Array.isArray(result)) {
        // 直接返回了数组
        chatIds.value = result.map(id => String(id));
      } else {
        // 无效数据，使用空数组
        console.warn('获取到的历史会话数据格式不正确:', result);
        chatIds.value = [];
      }
    } catch (apiError) {
      console.error('API调用失败，使用空会话列表:', apiError);
      chatIds.value = [];
    }
    
    console.log('处理后的chatIds:', chatIds.value);
    
    // 确保 chatIds.value 是数组
    if (!Array.isArray(chatIds.value)) {
      console.warn('处理后的 chatIds.value 不是数组，重置为空数组');
      chatIds.value = [];
    }
    
    // 如果当前没有选中的会话，或者选中的会话不在列表中，则选择第一个
    if (!currentChatId.value || !chatIds.value.includes(currentChatId.value)) {
      if (chatIds.value.length > 0) {
        selectChat(chatIds.value[0]);
      } else {
        createNewChat();
      }
    }
  } catch (error) {
    console.error('加载会话历史失败:', error);
    ElMessage.error('加载会话历史失败，创建新会话');
    // 出错时创建一个新会话
    createNewChat();
  }
};

// 选择会话
const selectChat = async (chatId) => {
  if (currentChatId.value === chatId) return;
  
  currentChatId.value = chatId;
  messages.value = [];
  
  try {
    const result = await getChatMessages(chatId);
    
    // 检查返回数据格式，确保 messages.value 是数组
    if (result && Array.isArray(result)) {
      messages.value = result;
    } else if (result && result.data && Array.isArray(result.data)) {
      messages.value = result.data;
    } else {
      console.warn('获取到的消息数据格式不正确:', result);
      messages.value = [];
    }
    
    // 滚动到底部
    await nextTick();
    scrollToBottom();
  } catch (error) {
    console.error('加载会话消息失败:', error);
    ElMessage.error('加载会话消息失败，请检查网络连接');
  }
};

// 删除会话
const deleteChat = async (chatId) => {
  try {
    await ElMessageBox.confirm('确定要删除此会话吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    
    try {
      // 尝试调用后端删除API
      try {
        await deleteChatHistory(chatId);
      } catch (apiError) {
        console.warn('后端删除API调用失败，仅删除前端数据:', apiError);
      }
      
      // 从列表中移除会话
      chatIds.value = chatIds.value.filter(id => id !== chatId);
      
      // 将更新后的聊天ID列表保存到本地存储
      saveChatIds(chatIds.value);
      
      // 从标题存储中移除
      if (chatTitles.value[chatId]) {
        delete chatTitles.value[chatId];
        saveChatTitles(); // 保存更新后的标题
      }
      
      // 如果删除的是当前会话，则选择第一个会话或创建新会话
      if (currentChatId.value === chatId) {
        if (chatIds.value.length > 0) {
          selectChat(chatIds.value[0]);
        } else {
          createNewChat();
        }
      }
      
      ElMessage.success('会话已删除');
    } catch (error) {
      console.error('删除会话失败:', error);
      ElMessage.error('删除会话失败，请稍后重试');
    }
  } catch {
    // 用户取消删除操作
  }
};

// 处理文件上传变更
const handleFileChange = (file) => {
  // 确保文件被添加到列表中
  if (file.status === 'ready') {
    // 文件已经准备好了
    console.log('文件已添加:', file.name, '类型:', file.raw?.type || '未知');
    
    // 防止文件重复添加
    const isDuplicate = fileList.value.some(f => f.uid === file.uid);
    if (!isDuplicate) {
      // 手动维护文件列表，确保文件被正确添加
      fileList.value.push(file);
      
      // 检查是否为图片文件
      if (file.raw && file.raw.type && file.raw.type.startsWith('image/')) {
        console.log('检测到图片文件:', file.name);
      }
    }
  }
};

// 处理文件移除
const handleFileRemove = (file) => {
  fileList.value = fileList.value.filter(f => f.uid !== file.uid);
  console.log('文件已移除:', file.name);
};

// 发送消息
const sendMessage = async () => {
  if ((!userInput.value.trim() && fileList.value.length === 0) || isLoading.value) return;
  
  // 如果没有当前会话，创建一个新会话
  if (!currentChatId.value) {
    createNewChat();
  }
  
  // 确保有文本内容，如果只有图片没有文本，则使用默认文本
  const userMessage = userInput.value.trim() || (fileList.value.length > 0 ? "[图片消息]" : "");
  console.log('触发发送消息:', userMessage, '文件数量:', fileList.value.length);
  
  try {
    // 确保 messages.value 是数组
    if (!Array.isArray(messages.value)) {
      console.warn('messages.value 不是数组，重置为空数组');
      messages.value = [];
    }
  
  // 添加用户消息到列表
  messages.value.push({
    role: 'user',
    content: userMessage
  });
  
  // 清空输入框
  userInput.value = '';
  
  // 滚动到底部
  await nextTick();
  scrollToBottom();
  
  // 准备发送数据
  const chatData = {
    prompt: userMessage,
    chatId: currentChatId.value,
      files: []
    };
    
    // 确保文件对象正确
    if (fileList.value && fileList.value.length > 0) {
      chatData.files = fileList.value.map(file => {
        if (file.raw) {
          console.log(`准备文件: ${file.name}, 类型: ${file.raw.type}`);
          return file.raw;
        } else {
          console.log(`准备文件: ${file.name}, 使用文件对象本身`);
          return file;
        }
      });
    }
    
    // 确保即使没有文字内容也能发送图片
    if (!chatData.prompt && chatData.files.length > 0) {
      chatData.prompt = "[图片消息]";
    }
    
    console.log('发送文件数量:', fileList.value.length, '文本内容:', chatData.prompt);
  
  // 清空文件列表
  fileList.value = [];
  
  // 设置加载状态
  isLoading.value = true;
    
    // 确保 messages.value 仍然是数组
    if (!Array.isArray(messages.value)) {
      console.warn('messages.value 在处理过程中变为非数组，重置为空数组');
      messages.value = [];
    }
  
  // 添加AI回复消息
  messages.value.push({
    role: 'assistant',
    content: ''
  });
  
  // 更新第一条消息的标题（如果是新会话的第一条消息）
  if (messages.value.length === 2 && messages.value[0].role === 'user') {
    // 使用用户的第一条消息作为标题
    const userFirstMessage = messages.value[0].content;
    // 去除HTML标签和特殊字符
    const plainText = userFirstMessage.replace(/<[^>]*>/g, '').trim();
    // 截取前30个字符作为标题
    chatTitles.value[currentChatId.value] = plainText.substring(0, 30) + 
      (plainText.length > 30 ? '...' : '');
    
    // 保存标题到本地存储
    saveChatTitles();
  }
  
    // 发送请求并处理流式响应
    console.time('AI响应时间');
    await sendChatMessage(chatData, (chunk) => {
      if (chunk) {
        // 确保 messages.value 是数组
        if (!Array.isArray(messages.value) || messages.value.length === 0) {
          console.warn('流式响应处理时 messages.value 异常，重置');
          messages.value = [{
            role: 'assistant',
            content: chunk
          }];
          return;
        }
        
        // 更新最后一条消息的内容
        const lastMessage = messages.value[messages.value.length - 1];
        lastMessage.content += chunk;
        
        // 滚动到底部
        nextTick(() => {
          scrollToBottom();
        });
      }
    });
    console.timeEnd('AI响应时间');
    
  } catch (error) {
    console.error('发送消息失败:', error);
    
    // 如果最后一条消息是空的AI回复，则更新它
    if (Array.isArray(messages.value) && messages.value.length > 0 && 
        messages.value[messages.value.length - 1].role === 'assistant') {
      const lastMessage = messages.value[messages.value.length - 1];
      
      if (!lastMessage.content || lastMessage.content.trim() === '') {
        lastMessage.content = '网络错误，请检查连接后重试。错误详情: ' + (error.message || '未知错误');
      }
    }
    
    ElMessage.error('发送消息失败: ' + (error.message || '未知错误'));
  } finally {
    isLoading.value = false;
  }
};

// 滚动到底部
const scrollToBottom = () => {
  if (messageList.value) {
    messageList.value.scrollTop = messageList.value.scrollHeight;
  }
};

// 监听消息列表变化，自动滚动到底部
watch(messages, () => {
  nextTick(() => {
    scrollToBottom();
  });
});

// 组件挂载时加载会话历史
onMounted(() => {
  // 先加载本地存储的标题
  loadChatTitles();
  // 然后加载会话历史
  loadChatHistory();
});

// 修复键盘事件处理
const handleSendMessage = (e) => {
  // 获取当前输入值，避免引用问题
  const currentInput = userInput.value?.trim();
  const currentFiles = fileList.value || [];
  
  // 如果是回车键且没有按Ctrl，阻止默认行为并发送消息
  if (e && e.type === 'keydown' && e.key === 'Enter' && !e.ctrlKey) {
    e.preventDefault(); // 阻止换行
  }
  
  // 确保在加载状态时不发送消息
  if (isLoading.value) {
    ElMessage.warning('正在等待AI回复，请稍候...');
    return;
  }
  
  // 允许只有文件没有文本的情况
  if (!currentInput && currentFiles.length === 0) {
    ElMessage.warning('请输入消息或上传文件');
    return;
  }
  
  console.log('准备发送消息:', {
    text: currentInput || '[图片消息]',
    files: currentFiles.length,
    chatId: currentChatId.value
  });
  
  // 检查token是否存在
  const token = localStorage.getItem('token');
  if (!token) {
    ElMessage.error('您尚未登录或会话已过期，请重新登录');
    return;
  }
  
  // 执行发送
  sendMessage();
};
</script>

<style scoped>
.chat-container {
  display: flex;
  height: 100vh;
  width: 100%;
  overflow: hidden;
}

.chat-sidebar {
  width: 280px;
  background-color: #f5f5f5;
  border-right: 1px solid #e0e0e0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.sidebar-header {
  padding: 16px;
  border-bottom: 1px solid #e0e0e0;
}

.new-chat-btn {
  width: 100%;
  margin-bottom: 10px;
}

.chat-type-selector {
  margin-top: 10px;
  display: flex;
  justify-content: center;
}

.chat-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.chat-item {
  padding: 12px;
  border-radius: 4px;
  margin-bottom: 8px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
}

.chat-item:hover {
  background-color: #f0f0f0;
}

.chat-item.active {
  background-color: #ecf5ff;
  border-color: #409eff;
}

.chat-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.delete-btn {
  margin-left: 8px;
}

.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.message-list {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background-color: #ffffff;
}

.message {
  display: flex;
  margin-bottom: 16px;
  align-items: flex-start;
}

.message-user {
  justify-content: flex-end;
}

.message-assistant {
  justify-content: flex-start;
}

.message-avatar {
  margin: 0 12px;
  flex-shrink: 0;
}

.message-content {
  padding: 12px;
  border-radius: 8px;
  max-width: calc(100% - 80px);
  overflow-wrap: break-word;
}

.user-message {
  background-color: #ecf5ff;
  margin-right: 4px;
  text-align: right;
}

.ai-message {
  background-color: #f0f9eb;
  margin-left: 4px;
  text-align: left;
}

.loading .dot {
  display: inline-block;
  width: 8px;
  height: 8px;
}

/* 文件预览样式 */
.preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px;
  max-height: 80vh;
  overflow: auto;
}

.preview-content {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.pdf-preview {
  width: 100%;
  height: 70vh;
  border: none;
}

.preview-error {
  color: #f56c6c;
  font-size: 16px;
  text-align: center;
}

.image-preview-wrapper {
  display: inline-block;
  cursor: pointer;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  margin: 4px;
  transition: all 0.3s;
}

.image-preview-wrapper:hover {
  border-color: #409eff;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
}

.preview-image {
  max-width: 100%;
  max-height: 300px;
  display: block;
  border-radius: 50%;
  background-color: #888;
  margin: 0 4px;
  animation: dot-pulse 1.5s infinite ease-in-out;
}

.loading .dot:nth-child(2) {
  animation-delay: 0.2s;
}

.loading .dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes dot-pulse {
  0%, 80%, 100% { transform: scale(0); }
  40% { transform: scale(1); }
}

.input-area {
  padding: 16px;
  border-top: 1px solid #e0e0e0;
  background-color: #ffffff;
}

.file-upload {
  margin-bottom: 16px;
}

.input-wrapper {
  display: flex;
  align-items: flex-end;
}

.input-wrapper .el-textarea {
  flex: 1;
  margin-right: 12px;
}

.send-btn {
  height: 40px;
  margin-bottom: 5px;
}

:deep(.el-upload-list) {
  margin-top: 8px;
}
</style>
